﻿using LogisticsTrackingWebApi_V3.Services;
using LogisticsTrackingWebApi_V3.ServicesImpl;
using LogisticsTrackingWebApi_V3.ServicesImpl.Providers;
using Microsoft.OpenApi.Models;
using Serilog;
using Swashbuckle.AspNetCore.SwaggerUI;
using System.Reflection;

namespace LogisticsTrackingWebApi_V3.Extensions
{
    public static class ServicesConfigure
    {
        public static void Configurations(this WebApplicationBuilder builder)
        {
            // 注册物流查询提供者（策略模式实现）
            builder.Services.AddScoped<ILogisticsProvider, SFExpressProvider>();
            builder.Services.AddScoped<ILogisticsProvider, YTOExpressProvider>();
            builder.Services.AddScoped<ILogisticsProvider, STOExpressProvider>();

            // 注册工厂
            builder.Services.AddScoped<LogisticsProviderFactory>();

            // 注册服务
            builder.Services.AddScoped<ILogisticsService, LogisticsService>();

        }

        public static void ConfigureServices(this WebApplicationBuilder builder)
        {
            // 添加缓存服务
            builder.Services.AddMemoryCache();

            // 注册日志服务
            builder.Services.AddLogging();

            builder.Services.AddControllers();

            builder.Services.AddEndpointsApiExplorer();

            builder.Services.AddSwagger();

            builder.Host.UseSerilog();
        }

        public static IServiceCollection AddSwagger(this IServiceCollection services)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            var xmlFilesPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            if (string.IsNullOrWhiteSpace(xmlFilesPath))
            {
                throw new ArgumentNullException(nameof(xmlFilesPath));
            }

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "v1",
                    Title = "v1接口文档",
                    Description = "v1接口文档"
                });

                var filePaths = Directory.GetFiles(xmlFilesPath, "*.xml", SearchOption.AllDirectories);
                if (filePaths.Any())
                {
                    foreach (var xmlPath in filePaths)
                    {
                        c.IncludeXmlComments(xmlPath, true);
                    }
                }

                c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
                c.IgnoreObsoleteActions();
                c.IgnoreObsoleteProperties();
                c.CustomSchemaIds(type => type.FullName);


                // 配置 Swagger 使用 JWT
                var securityScheme = new OpenApiSecurityScheme
                {
                    Name = "JWT Authentication",
                    Description = "Enter JWT Bearer token **_only_**",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.Http,
                    Scheme = "bearer", // 必须小写
                    BearerFormat = "JWT",
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme,
                        Id = "Bearer"
                    }
                };
                c.AddSecurityDefinition("Bearer", securityScheme);
                c.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    { securityScheme, new string[] { } }
                });

            });

            return services;
        }

        public static IApplicationBuilder UseSwaggerUI(this IApplicationBuilder builder)
        {
            return builder.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");

                c.DefaultModelsExpandDepth(-1);

                c.DocExpansion(DocExpansion.None);
            });
        }
    }
}
